package com.tbl.modules.wms.controller.move;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.tbl.common.utils.DateUtils;
import com.tbl.common.utils.PageTbl;
import com.tbl.common.utils.PageUtils;
import com.tbl.common.utils.StringUtils;
import com.tbl.modules.platform.constant.LogActionConstant;
import com.tbl.modules.platform.controller.AbstractController;
import com.tbl.modules.platform.service.system.LogService;
import com.tbl.modules.platform.util.DeriveExcel;
import com.tbl.modules.wms.constant.Constant;
import com.tbl.modules.wms.entity.move.MoveStorage;
import com.tbl.modules.wms.entity.move.MoveStorageDetail;
import com.tbl.modules.wms.service.move.MoveStorageDetailService;
import com.tbl.modules.wms.service.move.MoveStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 移库出库控制层
 * @author 70486
 */
@Controller
@RequestMapping("/moveout")
public class MoveOutController extends AbstractController {

    /**
     * 日志信息
     */
	@Autowired
	private LogService logService;
    /**
     * 移库处理-移库主表
     */
	@Autowired
	private MoveStorageService moveStorageService;
    /**
     * 移库处理-移库详情
     */
	@Autowired
	private MoveStorageDetailService moveStorageDetailService;

    /**
     * 跳转到移库出库管理页面
     * @return ModelAndView
     */
    @RequestMapping("/storageList")
    public ModelAndView storageList() {
        ModelAndView mv = this.getModelAndView();
        mv.setViewName("techbloom/move/moveout/moveout_list");
        return mv;
    }

    /**
     * 移库出库列表页数据
     * @param queryJsonString 查询条件
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/storageListData.do")
    @ResponseBody
    public Map<String, Object> storageListData(String queryJsonString) {
        Map<String, Object> map = new HashMap<>(5);
        if (!StringUtils.isEmptyString(queryJsonString)){
            map = JSON.parseObject(queryJsonString);
        }
        map.put("out", 1);
        PageTbl page = this.getPage();
        PageUtils utils = moveStorageService.getPageList(page, map);
        page.setTotalRows(utils.getTotalCount() == 0 ? 1 : utils.getTotalCount());
        //初始化分页对象
        executePageMap(map, page);
        map.put("rows", utils.getList());
        map.put("total", utils.getTotalPage() == 0 ? 1 : utils.getTotalPage());
        return map;
    }

    /**
     * 点击执行跳转到执行界面
     * @param id 移库单主键
     * @return ModelAndView
     */
    @RequestMapping(value = "/execute.do")
    @ResponseBody
    public ModelAndView execute(Integer id) {
        ModelAndView mv = this.getModelAndView();
        mv.addObject("id", id);
        mv.setViewName("techbloom/move/moveout/moveout_execute");
        return mv;
    }

    /**
     * 执行拣货操作列表
     * @param id 移库单主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/detailList.do")
    @ResponseBody
    public Map<String, Object> detailList(Integer id) {
        Map<String, Object> map = new HashMap<>(2);
        PageTbl page = this.getPage();
        PageUtils utils = moveStorageService.getPageDetailList(page, id);
        page.setTotalRows(utils.getTotalCount() == 0 ? 1 : utils.getTotalCount());
        //初始化分页对象
        executePageMap(map, page);
        map.put("rows", utils.getList());
        map.put("total", utils.getTotalPage() == 0 ? 1 : utils.getTotalPage());
        return map;
    }

    /**
     * 点击查看，跳转到列表页
     * @param id 移库单主键
     * @return ModelAndView
     */
    @RequestMapping(value = "/toInfo.do")
    @ResponseBody
    public ModelAndView toInfo(Long id) {
        ModelAndView mv = this.getModelAndView();
        mv.addObject("infoId", id);
        mv.setViewName("techbloom/move/moveout/moveout_info");
        return mv;
    }

    /**
     * 移库出库-点击编辑，跳转到编辑页面
     * @param id 移库单主键
     * @return ModelAndView
     */
    @RequestMapping(value = "/editInfo.do")
    @ResponseBody
    public ModelAndView editInfo(Long id) {
        ModelAndView mv = this.getModelAndView();
        mv.addObject("info", moveStorageService.selectById(id));
        mv.setViewName("techbloom/move/moveout/moveout_edit");
        return mv;
    }

    /**
     * 点击编辑，点击保存  保存主表信息
     * @param moveStorage 移库单
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/saveOutStorage")
    @ResponseBody
    public Map<String, Object> saveOutStorage(MoveStorage moveStorage) {
        Map<String, Object> map = new HashMap<>();
        moveStorageService.saveMoveStorage(moveStorage);
        map.put("result", true);
        map.put("msg", "保存成功！");
        return map;
    }

    /**
     * 点击编辑，点击提交，修改状态
     * @param moveStorage 移库单
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/subOutStorage")
    @ResponseBody
    public Map<String, Object> subOutStorage(MoveStorage moveStorage) {
        return moveStorageService.subMoveStorage(moveStorage);
    }

    /**
     * 点击编辑，获取质保单号列表
     * @param pageSize 页大小
     * @param pageNo 页码
     * @param id 移库单主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/getQaCode")
    @ResponseBody
    public Map<String, Object> getQaCode(int pageSize, int pageNo, Long id) {
        Map<String, Object> map = Maps.newHashMap();
        MoveStorage moveStorage = moveStorageService.selectById(id);
        if (moveStorage != null) {
            map.put("warehouseCode", moveStorage.getWarehouseCode());
            PageTbl page = this.getPage();
            page.setPagesize(pageSize);
            page.setPageno(pageNo);
            PageUtils utils = moveStorageService.getQaCode(page, map);
            map.put("result", utils.getList() == null ? "" : utils.getList());
            map.put("total", utils.getTotalPage() == 0 ? 1 : utils.getTotalPage());
        } else {
            map.put("result", "");
            map.put("total", 0);
        }
        return map;
    }

    /**
     * 点击编辑，发货单详情添加
     * @param id 移库单主键
     * @param qaCodeIds 库存主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/saveOutstorageDetail")
    @ResponseBody
    public Map<String, Object> saveOutstorageDetail(Long id, String[] qaCodeIds) {
        Map<String, Object> map = Maps.newHashMap();
        boolean result = moveStorageService.saveMoveStorageDetail(id, qaCodeIds);
        map.put("result", result);
        map.put("msg", result?"添加成功":"添加失败");
        return map;
    }

    /**
     * 点击编辑，删除详情数据
     * @param ids 移库详情主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/delOutstorageDetail")
    @ResponseBody
    public Map<String, Object> delDetail(String[] ids) {
        return moveStorageService.deleteMoveStorageDetailIds(ids);
    }

    /**
     * 点击出库执行，点击绑定行车  跳转行车绑定页面
     * @param detailId 移库单明细主键
     * @param infoId 移库单主键
     * @return ModelAndView
     */
    @RequestMapping(value = "/carbind.do")
    @ResponseBody
    public ModelAndView carbind(Long detailId, Long infoId) {
        ModelAndView mv = this.getModelAndView();
        MoveStorageDetail moveStorageDetail = moveStorageDetailService.selectById(detailId);
        mv.setViewName("techbloom/move/moveout/movecar_bind");
        mv.addObject("detail", moveStorageDetail);
        mv.addObject("carList", moveStorageService.selectCarListByWarehouseCode(moveStorageDetail.getWarehouseCode(),
                //okk
                Arrays.asList(getSessionUser().getFactoryCode().split(","))));
        mv.addObject("infoId", infoId);
        return mv;
    }

    /**
     * 点击出库执行，点击绑定行车  点击保存行车信息
     * @param detail 移库单明细
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/saveCar")
    @ResponseBody
    public Map<String, Object> saveCar(MoveStorageDetail detail) {
        Map<String, Object> map = Maps.newHashMap();
        boolean result = moveStorageService.saveCar(detail);
        map.put("result", result);
        map.put("msg", result?"行车绑定成功！":"绑定行车失败！");
        return map;
    }

    /**
     * 点击出库执行，点击开始拣货
     * @param id 移库详情主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/detailStart")
    @ResponseBody
    public Map<String, Object> detailStart(Long id) {
        Map<String, Object> map = Maps.newHashMap();
        boolean result;
        String msg;
        MoveStorageDetail moveStorageDetail = moveStorageDetailService.selectById(id);
        if (moveStorageDetail.getOutCarCode() == null) {
            msg = "请先绑定行车";
            map.put("msg", msg);
            return map;
        }
        if (moveStorageDetail.getState() == 2) {
            msg = "已经开始移库出库，请勿重新提交";
            map.put("msg", msg);
            return map;
        }
        if (moveStorageDetail.getState() == 3) {
            msg = "已进完成移库出库，请勿重复提交";
            map.put("msg", msg);
            return map;
        }
        if (moveStorageDetail.getState() == 4) {
            msg = "已开始移库入库操作，请勿重复提交";
            map.put("msg", msg);
            return map;
        }
        if (moveStorageDetail.getState() == 5) {
            msg = "已完成移库入库操作，请勿重复提交";
            map.put("msg", msg);
            return map;
        }
        result = moveStorageService.detailStart(id);
        map.put("result", result);
        map.put("msg", result?"更新成功":"更新失败");
        return map;
    }

    /**
     * 点击出库执行，点击拣货完成
     * @param id 移库详情主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/detailSuccess")
    @ResponseBody
    public Map<String, Object> detailSuccess(Long id) {
        Map<String, Object> map = Maps.newHashMap();
        boolean result = false;
        String msg;
        MoveStorageDetail moveStorageDetail = moveStorageDetailService.selectById(id);
        if (moveStorageDetail.getState() == Constant.INT_THREE) {
            msg = "已进完成移库出库，请勿重复提交";
        }else if (moveStorageDetail.getState() == Constant.INT_FOUR) {
            msg = "已开始移库入库操作，请勿重复提交";
        }else if (moveStorageDetail.getState() == Constant.INT_FIVE) {
            msg = "已完成移库入库操作，请勿重复提交";
        }else {
            result = moveStorageService.detailSuccess(id, getUserId());
            msg = result?"更新成功":"更新失败";
        }
        map.put("result", result);
        map.put("msg", msg);
        return map;
    }

    /**
     * 点击确认出库，把所有选中的移库明细出掉
     * @param ids 移库单明细主键数组
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/moveStorageOut")
    @ResponseBody
    public Map<String, Object> moveStorageOut(String[] ids) {
        List<Long> lstRemove = new ArrayList<>();

        List<Long> lstIds = Arrays.stream(ids).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        List<MoveStorageDetail> lstMoveStorageDetail = moveStorageDetailService.selectBatchIds(lstIds);
        lstMoveStorageDetail.forEach(moveStorageDetail->{
            if (moveStorageDetail.getState()==Constant.INT_THREE||moveStorageDetail.getState()==Constant.INT_FOUR||moveStorageDetail.getState()==Constant.INT_FIVE) {
                lstRemove.add(moveStorageDetail.getId());
            }
        });
        //去掉以及完成出库的明细
        lstIds.removeAll(lstRemove);

        return moveStorageService.moveStorageOut(lstIds, getUserId());
    }

    /**
     * 导出Excel
     * @param request
     * @param response
     */
    @RequestMapping(value = "/materialExcel", method = RequestMethod.POST)
    @ResponseBody
    public void materialExcel(HttpServletRequest request, HttpServletResponse response){
        Map<String, Object> map = new HashMap<>();
        map.put("ids", StringUtils.stringToInt(request.getParameter("ids")));
        map.put("moveCode", request.getParameter("queryMoveCode"));
        map.put("startTime", request.getParameter("queryStartTime"));
        map.put("endTime", request.getParameter("queryEndTime"));
        map.put("creater", request.getParameter("queryCreater"));
        map.put("factoryCode", request.getParameter("queryFactoryCode"));
        map.put("warehouse", request.getParameter("queryWarehouse"));

        try {
            String sheetName = "移库出库单" + "(" + DateUtils.getDay() + ")";
            response.setHeader("Content-Type", "application/force-download");
            response.setHeader("Content-Type", "application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Expires", "0");
            response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
            response.setHeader("Pragma", "public");
            response.setHeader("Content-disposition", "attachment;filename=" + new String(sheetName.getBytes("gbk"),
                    "ISO8859-1") + ".xls");

            Map<String, String> mapFields = new LinkedHashMap<>();
            String [] excelIndexArray = request.getParameter("queryExportExcelIndex").split(",");

            if (excelIndexArray.length==1&&"".equals(excelIndexArray[0])) {
                mapFields.put("moveCode", "移库单号");
                mapFields.put("moveTimeStr", "单据创建时间");
                mapFields.put("factoryName", "厂区");
                mapFields.put("userName", "创建人");
                mapFields.put("moveState", "单据状态");
            }else {
                for (String s : excelIndexArray) {
                    if ("2".equals(s)) {
                        mapFields.put("moveCode", "移库单号");
                    } else if ("3".equals(s)) {
                        mapFields.put("moveTimeStr", "单据创建时间");
                    } else if ("4".equals(s)) {
                        mapFields.put("factoryName", "厂区");
                    } else if ("5".equals(s)) {
                        mapFields.put("userName", "创建人");
                    } else if ("6".equals(s)) {
                        mapFields.put("moveState", "单据状态");
                    }
                }
            }

            DeriveExcel.exportExcel(sheetName, moveStorageService.getExcelList(map), mapFields, response, "");
            logService.logInsert("移库出库单", LogActionConstant.USER_EXPORT, request);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 调拨出库明细导出Excel
     * @param request
     * @param response
     */
    @RequestMapping(value = "/detailExcel.do", method = RequestMethod.POST)
    @ResponseBody
    public void detailExcel(HttpServletRequest request, HttpServletResponse response){
        Map<String, Object> map = new HashMap<>();
        map.put("id", request.getParameter("infoid"));
        map.put("ids", StringUtils.stringToInt(request.getParameter("ids")));

        try {
            String sheetName = "移库出库单" + "(" + DateUtils.getDay() + ")";
            response.setHeader("Content-Type", "application/force-download");
            response.setHeader("Content-Type", "application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Expires", "0");
            response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
            response.setHeader("Pragma", "public");
            response.setHeader("Content-disposition", "attachment;filename=" + new String(sheetName.getBytes("gbk"),
                    "ISO8859-1") + ".xls");

            Map<String, String> mapFields = new LinkedHashMap<>();

            mapFields.put("qaCode", "质保单号");
            mapFields.put("batchNo", "批次号");
            mapFields.put("materialCode", "物料编码");
            mapFields.put("materialName", "物料名称");
            mapFields.put("meter", "米数");
            mapFields.put("startOutStorageTimeStr", "开始拣货时间");
            mapFields.put("pickManName", "拣货人");
            mapFields.put("stateStr", "状态");

            mapFields.put("moveCode", "移库单号");
            mapFields.put("movetimeStr", "移库单据创建时间");
            mapFields.put("factoryName", "厂区");
            mapFields.put("username", "创建人");

            DeriveExcel.exportExcel(sheetName, moveStorageDetailService.getDetailExcelList(map), mapFields, response, "");
            logService.logInsert("移库出库单", LogActionConstant.USER_EXPORT, request);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
